﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>正则匹配 - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The 正则匹配 function determines whether a 字符串 contains a pattern (regular expression)." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>正则匹配</h1>

<p>判断字符串是否包含某个匹配模式(正则表达式).</p>

<pre class="Syntax">FoundPos := <span class="func">正则匹配</span>(Haystack, NeedleRegEx <span class="optional">, OutputVar, StartingPosition := 1</span>)</pre>
<h2 id="Parameters">参数</h2>
<dl>

  <dt>Haystack</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>要搜索其内容的字符串. 可能包含二进制零.</p>
  </dd>

  <dt>NeedleRegEx</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>要搜索的模式, 它是兼容 Perl 的正则表达式(PCRE). 模式的<a href="../misc/RegEx-QuickRef.htm#Options">选项</a>(如果有) 必须放在模式字符串的开始且后面跟着闭括号. 例如, 模式 &quot;<span class="red">i)</span>abc.*123&quot; 将匹配不区分大小写的 &quot;abc&quot;, 接着零个或多个任意字符, 然后是 &quot;123&quot;. 如果没有选项, &quot;)&quot; 是可选的; 例如, &quot;)abc&quot; 等同于 &quot;abc&quot;.</p>
    <p>虽然 <em>NeedleRegEx</em> 不能包含二进制零, 但模式 <code>\x00</code> 可用来匹配 <em>Haystack</em> 中的二进制零.</p>
  </dd>

  <dt>OutputVar</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#variables">变量</a></p>
    <p>指定一个变量, 在其中存储<a href="#MatchObject">匹配对象</a>, 可以用来获取整体匹配和每个<a href="../misc/RegEx-QuickRef.htm#subpat">捕获子模式</a>(如果存在) 的位置, 长度和值.</p>
    <p>如果没有找到模式(也就是说, 如果函数返回 0), 这个变量将被置空.</p>
  </dd>

  <dt>StartingPosition</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
    <p>如果省略 <em>StartingPosition</em>, 则它默认为 1(<em>Haystack</em> 的开始位置). 否则, 指定 2 从第二个字符开始, 3 从第三个字符开始, 以此类推. 如果 <em>StartingPosition</em> 的长度超过 <em>Haystack</em> 的长度, 那么搜索将从 <em>Haystack</em> 末尾的空字符串开始(常结果是不匹配).</p>
    <p>指定负值的 <em>StartingPosition</em>, 从右边的位置开始搜索. 例如, -1 从最后一个字符开始, -2 从倒数第二个字符开始. 如果 <em>StartingPosition</em> 试图超出 <em>Haystack</em> 的左端, 则会搜索整个 <em>Haystack</em>.</p>
    <p>不论 <em>StartingPosition</em> 的值是多少, 返回的值总是相对于 <em>Haystack</em> 的第一个字符. 例如, &quot;abc&quot; 在 &quot;123abc789&quot; 中的位置总是 4.</p>
  </dd>

</dl>

<h2 id="Return_Value">返回值</h2>
<p>类型: <a href="../Concepts.htm#numbers">整数</a></p>
<p>函数返回在字符串 <em>Haystack</em> 中最左边出现 <em>NeedleRegEx</em> 的位置. 位置 1 表示第一个字符. 如果没有找到模式, 则返回 0.</p>

<h2 id="Errors">错误</h2>
<p><strong>语法错误:</strong> 如果模式中包含语法错误, 则抛出<a href="Throw.htm#Exception">异常</a>, 并带有以下形式的消息: <em>Compile error N at offset M: description</em>. 在该字符串中, <em>N</em> 是 PCRE 中错误的编号, <em>M</em> 是正则表达式中违规字符的位置, 而 <em>description</em> 是描述该错误的文本.</p>
<p><strong>执行错误:</strong> 如果在 <em>执行</em> 正则表达式的过程中发生错误, 则抛出<a href="Throw.htm#Exception">异常</a>. 异常对象的 <em>Extra</em> 属性包含了 PCRE 的错误编号. 虽然这种错误很少发生, 但最有可能发生的是 &quot;"太多空字符串匹配&quot;(-22), &quot;递归太深&quot;(-21), 和 &quot;达到匹配限制&quot;(-8). 如果出现这些情况, 请尝试重新设计更严格的匹配模式, 例如无论是否可行都把每个 * 替换为 ?, + 或像 {0,3} 这样的限制.</p>

<h2 id="Options">选项</h2>
<p>请参阅<a href="../misc/RegEx-QuickRef.htm#Options">选项</a>了解修饰符, 例如 &quot;<span class="red">i)</span>abc&quot;, 它关闭了模式 &quot;abc&quot; 的区分大小写.</p>

<h2 id="MatchObject">匹配对象</h2>
<p>如果找到了匹配, 一个包含匹配信息的对象将被存储在 <em>OutputVar</em>. 这个对象有以下属性:</p>
<p><strong>Match.Pos(N)</strong>: 返回整个匹配或捕获子模式的位置.</p>
<p><strong>Match.Len(N)</strong>: 返回整个匹配或捕获子模式的长度.</p>
<p><strong>Match.Value(N)</strong>: 返回整个匹配或捕获子模式.</p>
<p><strong>Match.Name(N)</strong>: 返回指定的子模式的名称(如果它含有).</p>
<p><strong>Match.Count()</strong>: 返回所有子模式的数目.</p>
<p><strong>Match.Mark()</strong>: 适用时返回上次遇到 <code>(*MARK:NAME)</code> 的 <em>NAME</em>.</p>
<p><strong>Match[N]</strong>: 如果 <em>N</em> 为 0 或有效的子模式编号或名称, 那么它相当于 <code>Match.Value(N)</code>.</p>
<p><strong>Match.N</strong>: 与上面相同, 不过这里 <em>N</em> 为未加引号的名称或编号.</p>
<p>对于上面的所有属性, <em>N</em> 可以为下列值:</p>
<ul>
  <li>0 表示整个匹配.</li>
  <li>子模式的编号, 包括含有名称的子模式.</li>
  <li>子模式的名称.</li>
</ul>
<p>该对象还支持枚举; 也就是说, 支持 <a href="For.htm">遍历-loop</a>. 或者, 可以使用 <code><a href="Loop.htm">循环</a> Match.Count()</code>.</p>

<h2 id="Performance">性能</h2>
<p>要在一个较大的字符串中搜索简单的子字符串, 请使用 <a href="InStr.htm">查找</a>, 因为它比 正则匹配 更快.</p>
<p>为了提升性能, 最近使用的 100 个正则表达式会被缓存在内存中(以已编译的形式).</p>
<p>多次使用一个正则表达式时(例如在循环中), 使用<a href="../misc/RegEx-QuickRef.htm#Study">研究选项(S)</a> 可以提高性能.</p>

<h2 id="Remarks">备注</h2>
<p id="NamedSubPat">可以为子模式指定名称, 例如模式 &quot;(?P&lt;Year&gt;\d{4})&quot; 中的单词 <em>Year</em>. 这种名称最多可以由 32 个字母数字和下划线组成. 请注意, 命名的子模式也是有编号的, 如果在 &quot;Year&quot; 后出现了一个<a href="../misc/RegEx-QuickRef.htm#subpat">未命名的子模式</a>, 它将被存储在 <code>OutputVar[2]</code> 中, 而不是 <code>OutputVar[1]</code> 中.</p>
<p>大多数字符, 如 abc123 可以原义使用在正则表达式中. 然而, <strong>\.*?+[{|()^$</strong> 这些字符则必须在其前面加上反斜杠才能被视为原义. 例如, <strong>\.</strong> 表示一个原义的句点, 而 <strong>\\</strong> 表示一个原义的反斜杠. 使用 \Q...\E 能避免转义. 例如: <code>\QLiteral Text\E</code>.</p>
<p>在正则表达式中, 特殊字符(如制表符和换行符) 可以使用一个重音符(`) 或反斜杠(\) 进行转义. 例如, 在不使用 <b>x</b> 选项时, `t 等同于 \t.</p>
<p>要了解正则表达式的基础(或复习正则表达式的语法), 请参阅<a href="../misc/RegEx-QuickRef.htm">正则表达式快速参考</a>.</p>
<p>AutoHotkey 的正则表达式是使用 <a href="http://www.pcre.org/">www.pcre.org</a> 的兼容 Perl Regular Expressions(PCRE) 实现的.</p>
<p>在<a href="../Variables.htm#Expressions">表达式</a>中, <code>a <a href="../Variables.htm#regex">~=</a> b</code> 能被当作 <code>正则匹配(a, b)</code> 的缩写.</p>
<h2 id="Related">相关</h2>
<p><a href="RegExReplace.htm">正则替换</a>, <a href="../misc/RegEx-QuickRef.htm">RegEx 快速参考</a>, <a href="../misc/RegExCallout.htm">Regular Expression Callouts</a>, <a href="InStr.htm">查找</a>, <a href="SubStr.htm">截取字符串</a>, <a href="SetTitleMatchMode.htm#RegEx">设置标题匹配模式 RegEx</a>, <a href="https://www.autohotkey.com/forum/topic16164.html">Global matching and Grep (forum link)</a></p>
<p>文本数据的常见来源: <a href="FileRead.htm">读文件</a>, <a href="Download.htm">下载</a>, <a href="../misc/A_Clipboard.htm">内_剪贴板</a>, <a href="GuiControls.htm#Edit">界面 Edit 控件</a></p>

<h2 id="Examples">示例</h2>
<p>有关普通 RegEx 的示例, 请参阅 <a href="../misc/RegEx-QuickRef.htm">RegEx 快速参考</a>.</p>

<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a></p>
<pre>信息框 正则匹配(&quot;xxxabc123xyz&quot;, &quot;abc.*xyz&quot;)  <em>; 显示 4, 这是找到匹配的位置.</em>
信息框 正则匹配(&quot;abc123123&quot;, &quot;123$&quot;)  <em>; 显示 7, 因为 $ 要求在末端进行匹配.</em>
信息框 正则匹配(&quot;abc123&quot;, &quot;i)^ABC&quot;)  <em>; 显示 1, 因为通过不区分大小写选项实现了匹配.</em>
信息框 正则匹配(&quot;abcXYZ123&quot;, &quot;abc(.*)123&quot;, SubPat)  <em>; 显示 1, 并把 &quot;XYZ&quot; 保存到 SubPat[1].</em>
信息框 正则匹配(&quot;abc123abc456&quot;, &quot;abc\d+&quot;,, 2)  <em>; 显示 7 而不是 1, 这是由于 StartingPosition 为 2 而不是 1.</em></pre>
</div>

<div class="ex" id="ExObject">
<p><a href="#ExObject">#2</a>: 匹配对象</p>
<pre>FoundPos := 正则匹配(&quot;Michiganroad 72&quot;, &quot;(.*) (?&lt;nr&gt;\d+)&quot;, SubPat)
信息框 SubPat.Count() ": " SubPat.Value(1) " " SubPat.Name(2) "=" SubPat["nr"]  <em>; 显示 "2: Michiganroad nr=72"</em></pre>
</div>

<div class="ex" id="ExExtension">
<p><a href="#ExExtension">#3</a>: 一个检索文件扩展名的简单示例. 注意 <a href="SplitPath.htm">分割路径</a> 也可以用于此目的, 而且更可靠.</p>
<pre>Path := "C:\Foo\Bar\Baz.txt"
正则匹配(Path, "\w+$", Extension)
信息框 Extension[0]  <em>; 显示 "txt".</em></pre>
</div>

</body>
</html>